/*
 * @Author: c
 * @Date: 2024-02-06 10:39:42
 * @LastEditTime: 2024-03-16 18:18:33
 * @LastEditors: c
 * @Description: 
 * @FilePath: \music-web-backend\src\core\music\banner\dao\banner.dao.ts
 * https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
// Copyright 2024 Administrator
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { MinioClientService } from "src/core/system/minio/minio.service";
import { DataSource, Repository } from "typeorm";
import { BannerForm } from "../dto/create-banner.dto";
import { Banner } from "../entities/banner.entity";
import { IBanner } from "../interface/banner.interface";

@Injectable()
export class DBanner implements IBanner {


    constructor(
        @InjectRepository(Banner) private bannerRepository: Repository<Banner>,
        private dataSource: DataSource,
        private minioClientService: MinioClientService,
    ) { }

    async update(banner: Banner, bannerForm: BannerForm) {
        const newBanner = await this.bannerRepository.merge(banner, bannerForm)
        this.bannerRepository.save(newBanner);
    }

    deleteById(ids: number | number[]) {
        this.bannerRepository.delete(ids);
    }

    getOneByOutputId(id: number): Promise<Banner> {
        return this.bannerRepository.findOne({ where: { jumpLinkOutput: id } })
    }

    getOneById(id: number) {
        return this.bannerRepository.findOne({ where: { id } })
    }

    async create(banner: Banner): Promise<Banner> {
        try {
            return await this.bannerRepository.save(banner)
        } catch (error) {
            return
        }
    }


    /**
     * 轮播图-下拉列表查询
     * @param pageNum 
     * @param pageSize 
     * @param alubmName 
     */
    async listOptions(pageNum: number, pageSize: number, alubmName: string): Promise<Banner[]> {
        const build = await this.bannerRepository
            .createQueryBuilder("banner")
            .select([
                'banner.id',
                'banner.title',
            ])
            .orderBy("banner.createTime", 'DESC')
            .offset((pageNum - 1) * pageSize)
            .limit(pageSize)



        if (alubmName) {
            build.where('banner.title like :keywords', { keywords: `%${alubmName}%` });
        }

        const data = await build.getMany();

        return data
    }


    /**
     * 轮播图-单条数据查询
     * @param id 轮播图id
     * @param username 当前登录用户名
     * @returns 
     */
    async getOneByIdAndUsername(id: number, username: string): Promise<Banner> {
        const build = await this.bannerRepository
            .createQueryBuilder("banner")
            .leftJoinAndSelect("banner.artistList", "artist")
            .leftJoinAndSelect("banner.pic", "file_info_pic")
            .leftJoinAndSelect("banner.trackList", "song")
            .leftJoinAndSelect("song.rateFileInfos", "rate_file_info")
            .leftJoinAndSelect("song.paidUsers", "paid_user", "paid_user.username = :useranme")
            .leftJoinAndSelect("banner.favoriteUsers", "favor_user", "favor_user.username = :useranme")
            .leftJoinAndSelect('banner.genre', "genre")
            .setParameter('useranme', username)
            .select([
                'banner.id',
                'banner.title',
                'banner.lang',
                'banner.releaseDate',
                'banner.pushTime',
                'banner.downTime',
                'banner.payModel',
                'banner.createTime',
                'banner.isActive',
                'banner.introduce',
                'artist.id',
                'artist.name',
                'song.id',
                'song.title',
                'song.isVip',
                'song.payModel',
                'song.sort',
                'rate_file_info.size',
                'rate_file_info.rate',
                'rate_file_info.format',
                'rate_file_info.duration',
                'genre.id',
                'genre.categoryName',
                'favor_user.id',
                'favor_user.username',
                'paid_user.id',
                'paid_user.username',
                'file_info_pic.id',
                'file_info_pic.percentage',
                'file_info_pic.url',
                'file_info_pic.name',
                'file_info_pic.mimeType',
                'file_info_pic.uid',
                'file_info_pic.lastModified',
            ]).where("banner.id = :id", { id })


        const data = await build.getOne();

        return data
    }


    async page(pageNum: number, pageSize: number, validTime: Date = new Date()): Promise<[Banner[], number]> {
        const build = await this.bannerRepository
            .createQueryBuilder("banner")
            .select([
                'banner.id',
                'banner.jumpType',
                'banner.jumpLinkOutput',
                'banner.sort',
                'banner.showStartDate',
                'banner.showEndDate'
            ])
            .orderBy("banner.sort", 'DESC')
            .offset((pageNum - 1) * pageSize)
            .limit(pageSize)

        if (validTime) {
            build.where('banner.showEndDate > :time', { time: validTime });
        }

        const [data, total] = await build.getManyAndCount();

        return [data, total]
    }


}